package main

import (
	"bufio"
	"fmt"
	"log"
	"strings"

	"github.com/google/gopacket"
	"github.com/google/gopacket/layers"
	"github.com/google/gopacket/pcap"
)

func main() {
	// 1. 打开网络设备
	iface := "ens192"
	handle, err := pcap.OpenLive(iface, 1600, true, pcap.BlockForever)
	if err != nil {
		log.Fatalf("无法打开设备 %s: %v", iface, err)
	}
	defer handle.Close()

	// 2. 设置 BPF 过滤器，只捕获 HTTP 常用端口的 TCP 流量
	// 过滤端口 80 (HTTP) 和 8080 (常用 HTTP 替代端口)
	// if err := handle.SetBPFFilter("tcp port 3001 or tcp port 3000"); err != nil {
	// 	log.Fatalf("过滤器设置失败: %v", err)
	// }
	if err := handle.SetBPFFilter("tcp"); err != nil {
		log.Fatalf("过滤器设置失败: %v", err)
	}

	// 3. 循环捕获并解析数据包
	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
	for packet := range packetSource.Packets() {
		processPacket(packet)
	}
}

// processPacket 处理单个数据包，提取 HTTP 信息
func processPacket(packet gopacket.Packet) {
	// 解析链路层
	ethLayer := packet.Layer(layers.LayerTypeEthernet)
	if ethLayer == nil {
		return
	}
	eth := ethLayer.(*layers.Ethernet)

	// 解析网络层 (IPv4)
	ipLayer := packet.Layer(layers.LayerTypeIPv4)
	if ipLayer == nil {
		return
	}
	ip := ipLayer.(*layers.IPv4)

	// 解析传输层 (TCP)
	tcpLayer := packet.Layer(layers.LayerTypeTCP)
	if tcpLayer == nil {
		return
	}
	tcp := tcpLayer.(*layers.TCP)

	// 解析应用层数据
	appLayer := packet.ApplicationLayer()
	if appLayer == nil {
		return
	}
	payload := appLayer.Payload()
	if len(payload) == 0 {
		return
	}

	// 区分 HTTP 请求和响应
	if isHTTPRequest(payload) {
		parseHTTPRequest(payload, eth, ip, tcp)
	} else if isHTTPResponse(payload) {
		parseHTTPResponse(payload, eth, ip, tcp)
	}
}

// isHTTPRequest 判断是否为 HTTP 请求（通过请求方法开头）
func isHTTPRequest(payload []byte) bool {
	methods := []string{"GET ", "POST ", "PUT ", "DELETE ", "HEAD ", "OPTIONS "}
	for _, m := range methods {
		if strings.HasPrefix(string(payload), m) {
			return true
		}
	}
	return false
}

// isHTTPResponse 判断是否为 HTTP 响应（通过 HTTP/ 开头）
func isHTTPResponse(payload []byte) bool {
	return strings.HasPrefix(string(payload), "HTTP/")
}

// parseHTTPRequest 解析 HTTP 请求
func parseHTTPRequest(payload []byte, eth *layers.Ethernet, ip *layers.IPv4, tcp *layers.TCP) {
	// 分割请求头和请求体（通过 \r\n\r\n 分隔）
	parts := strings.SplitN(string(payload), "\r\n\r\n", 2)
	headersStr := parts[0]
	body := ""
	if len(parts) > 1 {
		body = parts[1]
	}

	// 解析请求行
	lines := strings.Split(headersStr, "\r\n")
	if len(lines) == 0 {
		return
	}
	requestLine := lines[0]
	requestParts := strings.Split(requestLine, " ")
	if len(requestParts) < 3 {
		return
	}
	method := requestParts[0]
	path := requestParts[1]

	// 解析 Host 头
	host := ""
	scanner := bufio.NewScanner(strings.NewReader(headersStr))
	for scanner.Scan() {
		line := scanner.Text()
		if strings.HasPrefix(line, "Host: ") {
			host = strings.TrimPrefix(line, "Host: ")
			break
		}
	}

	// 输出结果
	fmt.Printf("[HTTP 请求]\n")
	fmt.Printf("  源 MAC: %s\n", eth.SrcMAC)
	fmt.Printf("  源 IP: %s:%d\n", ip.SrcIP, tcp.SrcPort)
	fmt.Printf("  目标 IP: %s:%d\n", ip.DstIP, tcp.DstPort)
	fmt.Printf("  方法: %s\n", method)
	fmt.Printf("  URL: http://%s%s\n", host, path)
	fmt.Printf("  请求头:\n%s\n", headersStr)
	if body != "" {
		fmt.Printf("  请求体:\n%s\n", body)
	}
	fmt.Printf("-------------------------\n")
}

// parseHTTPResponse 解析 HTTP 响应
func parseHTTPResponse(payload []byte, eth *layers.Ethernet, ip *layers.IPv4, tcp *layers.TCP) {
	// 分割响应头和响应体
	parts := strings.SplitN(string(payload), "\r\n\r\n", 2)
	headersStr := parts[0]
	body := ""
	if len(parts) > 1 {
		body = parts[1]
	}

	// 解析状态行
	lines := strings.Split(headersStr, "\r\n")
	if len(lines) == 0 {
		return
	}
	statusLine := lines[0]

	// 输出结果
	fmt.Printf("[HTTP 响应]\n")
	fmt.Printf("  源 MAC: %s\n", eth.SrcMAC)
	fmt.Printf("  源 IP: %s:%d\n", ip.SrcIP, tcp.SrcPort)
	fmt.Printf("  目标 IP: %s:%d\n", ip.DstIP, tcp.DstPort)
	fmt.Printf("  状态行: %s\n", statusLine)
	fmt.Printf("  响应头:\n%s\n", headersStr)
	if body != "" {
		fmt.Printf("  响应体:\n%s\n", body)
	}
	fmt.Printf("-------------------------\n")
}
